package com.zimmur.app.mocolink.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.RedisSystemException;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.zimmur.app.mocolink.dao.GoodsTypeMapper;
import com.zimmur.app.mocolink.domain.common.Constant;
import com.zimmur.app.mocolink.domain.model.BackgroundImage;
import com.zimmur.app.mocolink.domain.model.GoodsType;
import com.zimmur.app.mocolink.domain.model.GoodsTypeExample;
import com.zimmur.app.mocolink.domain.vo.GoodsCategoryInfo;
import com.zimmur.app.mocolink.domain.vo.GoodsCategoryVo;
import com.zimmur.app.mocolink.domain.vo.GoodsTypeInfo;
import com.zimmur.app.mocolink.domain.vo.GoodsTypeVo;
import com.zimmur.app.mocolink.service.IGoodsCategoryService;
import com.zimmur.app.mocolink.service.RedisCacheUtil;
 
@Service
public class GoodsCategoryServiceImpl implements IGoodsCategoryService{
	private static final Logger log = LoggerFactory.getLogger(GoodsCategoryServiceImpl.class);
	@Autowired
	private GoodsTypeMapper goodsTypeMapper;
	@Autowired
	private RedisCacheUtil<String> redisUtil;
	private static final String redis_key="mocolink_type_used"; 
	@Override
	public List<GoodsCategoryVo> queryEntireCategory() {
		String key=redis_key;
		String json;
		List<GoodsCategoryVo> vo;
		boolean isExist=redisUtil.exists(redis_key);
		if(isExist){
			json = redisUtil.getCacheString(key);
			vo=JSONObject.parseArray(json, GoodsCategoryVo.class);
		}else{
			synchronized (redis_key) {
				isExist=redisUtil.exists(key);
				if(isExist){
					json = redisUtil.getCacheString(key);
					vo=JSONObject.parseArray(json, GoodsCategoryVo.class);
				}else{
					vo = getAllType();
					if(vo!=null){
						json = JSONObject.toJSONString(vo);
						try {
							redisUtil.setCacheString(key, json);
							redisUtil.setTimeout(key, redisUtil.longTime);
						} catch (RedisSystemException e) {
							log.error("redis save error,info:{}",e);
						}
					}
				}
			}
		}
		return vo;
	}

	@Override
	public List<GoodsTypeVo> selectByGradeWithChild(Integer grade, Integer parentId) {
		return goodsTypeMapper.selectByGradeWithChild(grade, parentId);
	}

	@Override
	public GoodsType selectById(Integer typeId) {
		return goodsTypeMapper.selectByPrimaryKey(typeId);
	}

	@Override
	public int update(GoodsType goodsType) {
		int flag = goodsTypeMapper.updateByPrimaryKeySelective(goodsType);
		if(flag>0){
			deleteRedis();
		}
		return flag;
	}

	@Override
	public int add(GoodsType goodsType) {
		int flag = goodsTypeMapper.insertSelective(goodsType);
		if(flag>0){
			deleteRedis();
		}
		return flag;
	}
	private void deleteRedis(){
		try {
			boolean isExist=redisUtil.exists(redis_key); 
			if(isExist){
				redisUtil.del(redis_key);
			}
		} catch (RedisSystemException e) {
			log.error("delete redis error——goodsType,message:{}",e);
		}
	}
	private List<GoodsCategoryVo> getAllType(){
		List<GoodsCategoryVo> vo = new ArrayList<GoodsCategoryVo>();
		GoodsTypeExample ex = new GoodsTypeExample();
		ex.createCriteria().andGradeEqualTo(1);
		List<GoodsType> goodTypeList= goodsTypeMapper.selectByExample(ex);
		if(goodTypeList!=null&&!goodTypeList.isEmpty()){
			for(GoodsType type:goodTypeList){
				//1.查询第一级品类信息
				GoodsCategoryVo voInfo = new GoodsCategoryVo();
				List<GoodsCategoryInfo> secondChildList = new ArrayList<>();
				voInfo.setCategoryName(type.getName());
				voInfo.setCategoryId(type.getId());
				voInfo.setEnglishName(type.getEnglishName());
				voInfo.setGrade(type.getGrade());
				voInfo.setIcon(type.getIcon());
				voInfo.setParentId(type.getParentId());
				
				GoodsTypeExample second = new GoodsTypeExample();
				second.createCriteria().andParentIdEqualTo(type.getId());
				List<GoodsType> secondList= goodsTypeMapper.selectByExample(second);
				if(secondList!=null&&!secondList.isEmpty()){
					//2.查询第二级品类信息
					for(GoodsType secType:secondList){
						GoodsCategoryInfo cateInfo = new GoodsCategoryInfo();
						List<GoodsTypeInfo> thirdChildList = new ArrayList<GoodsTypeInfo>();
						cateInfo.setCategoryName(secType.getName());
						cateInfo.setCategoryId(secType.getId());
						cateInfo.setEnglishName(secType.getEnglishName());
						cateInfo.setGrade(secType.getGrade());
						cateInfo.setIcon(secType.getIcon());
						cateInfo.setParentId(secType.getParentId());
						
						//3.查询第三级品类信息
						GoodsTypeExample third = new GoodsTypeExample();
						third.createCriteria().andParentIdEqualTo(secType.getId());
						List<GoodsType> thirdList= goodsTypeMapper.selectByExample(third);
						if(thirdList!=null&&!thirdList.isEmpty()){
							//4.查询第四级品类信息
							for(GoodsType thirdType:thirdList){
								GoodsTypeInfo typeInfo = new GoodsTypeInfo();
								typeInfo.setCategoryId(thirdType.getId());
								typeInfo.setCategoryName(thirdType.getName());
								typeInfo.setEnglishName(thirdType.getEnglishName());
								typeInfo.setGrade(thirdType.getGrade());
								typeInfo.setIcon(thirdType.getIcon());
								typeInfo.setParentId(thirdType.getParentId());
								GoodsTypeExample four = new GoodsTypeExample();
								four.createCriteria().andParentIdEqualTo(thirdType.getId());
								List<GoodsType> fourChildList= goodsTypeMapper.selectByExample(four);
								
								typeInfo.setFourChildList(fourChildList);
								thirdChildList.add(typeInfo);
							}
						}
						cateInfo.setThirdChildList(thirdChildList);
						secondChildList.add(cateInfo);
					}
				}
				voInfo.setSecondChildList(secondChildList);
				vo.add(voInfo);
			}
		}
		return vo;
	}

	@Override
	public int delete(Integer typeId) {
		GoodsType goodsType = goodsTypeMapper.selectByPrimaryKey(typeId);
		if(goodsType == null){
			return -1;
		}
		if(goodsType.getGrade()==Constant.Goods_Type_Grade_Final){
			
		}else{
			GoodsTypeExample example = new GoodsTypeExample();
			example.createCriteria().andParentIdEqualTo(typeId);
			int count = goodsTypeMapper.countByExample(example);
			if(count>0){
				return -2;
			}
			
		}
		int flag = goodsTypeMapper.deleteByPrimaryKey(typeId);
		if(flag>0){
			deleteRedis();
		}
		return flag;
	}

	@Override
	public List<GoodsTypeVo> selectAll() {
		List<GoodsTypeVo> list = goodsTypeMapper.selectByIsUsed(null);
		List<GoodsTypeVo> typeList=new ArrayList<>();
		if(list!=null){
			Map<Integer,GoodsTypeVo> map = new HashMap<>();
			for(GoodsTypeVo vo:list){
				vo.setChildrenList(new ArrayList<GoodsTypeVo>());
				map.put(vo.getTypeId(), vo);
			}
			for(GoodsTypeVo vo:list){
				if(vo.getGrade()>1){
					GoodsTypeVo parent = map.get(vo.getParentId());
					if(parent!=null){
						parent.getChildrenList().add(vo);
					}
				}else{
					typeList.add(vo);
				}
			}
		}
		return typeList;
	}

	@Override
	public List<GoodsTypeVo> selectUsed() {
		String key=redis_key;
		String json;
		List<GoodsTypeVo> typeList;
		boolean isExist=redisUtil.exists(redis_key);
		if(isExist){
			json = redisUtil.getCacheString(key);
			typeList=JSONObject.parseArray(json, GoodsTypeVo.class);
		}else{
			synchronized (redis_key) {
				isExist=redisUtil.exists(key);
				if(isExist){
					json = redisUtil.getCacheString(key);
					typeList=JSONObject.parseArray(json, GoodsTypeVo.class);
				}else{
					List<GoodsTypeVo> list = goodsTypeMapper.selectByIsUsed(Constant.byte_1);
					typeList=new ArrayList<>();
					if(list!=null){
						Map<Integer,GoodsTypeVo> map = new HashMap<>();
						for(GoodsTypeVo vo:list){
							vo.setChildrenList(new ArrayList<GoodsTypeVo>());
							map.put(vo.getTypeId(), vo);
						}
						for(GoodsTypeVo vo:list){
							if(vo.getGrade()>1){
								GoodsTypeVo parent = map.get(vo.getParentId());
								if(parent!=null){
									parent.getChildrenList().add(vo);
								}
							}else{
								typeList.add(vo);
							}
						}
					}
					if(typeList!=null && typeList.size()>0){
						json = JSONObject.toJSONString(typeList);
						try {
							redisUtil.setCacheString(key, json);
							redisUtil.setTimeout(key, redisUtil.shortTime);
						} catch (RedisSystemException e) {
							log.error("redis save error,info:{}",e);
						}
					}
				}
			}
		}
		return typeList;
	}

	@Override
	public int updateStatus(Integer typeId) {
		int flag = 0;
		GoodsType goodsType = goodsTypeMapper.selectByPrimaryKey(typeId);
		if(goodsType.getIsUsed()==1){
			if(goodsType.getGrade()!=Constant.Goods_Type_Grade_Final){
				int grade = goodsType.getGrade();
				List<Integer> typeList=new ArrayList<>();
				List<Integer> typeIdList=new ArrayList<>();
				typeIdList.add(typeId);
				while(grade<4){
					typeIdList = goodsTypeMapper.selectByParentId(typeIdList);
					if(typeIdList==null || typeIdList.size()==0){
						break;
					}
					typeList.addAll(typeIdList);
					grade++;
				}
				if(typeList.size()>0){
					goodsTypeMapper.batchUpdateGoodsTypeStatus(typeList);
				}
			}
			
			goodsType.setIsUsed(Constant.byte_0);
		}else{
			if(goodsType.getGrade()!=Constant.Goods_Type_Grade_Final){
				GoodsTypeExample example = new GoodsTypeExample();
				example.createCriteria().andParentIdEqualTo(typeId);
				int count = goodsTypeMapper.countByExample(example);
				if(count == 0){
					flag = -1;
				}
			}
			goodsType.setIsUsed(Constant.byte_1);
				
		}
		if(flag == 0){
			flag = goodsTypeMapper.updateByPrimaryKeySelective(goodsType);
			deleteRedis();
		}
		return flag;
	}
}
